<template>
  <div class="export-button">
    <div v-if="isDiy" @click="beforeExport">
      <slot />
    </div>
    <template v-else>
      <el-tooltip :content="tooltipContent" effect="dark" placement="top">
        <el-button
          :loading="loading"
          type="text"
          size="small"
          class="btn-operate btn-export"
          data-tooltip="导出"
          style="padding: 0;display:flex;align-items:center;"
          @click="beforeExport">
          <span style="display:flex;"><img :src="templateImg || exportImg" :style="{width: width + 'px', height: height + 'px'}" alt="导出订单"></span>
        </el-button>
      </el-tooltip>
    </template>

  </div>
</template>
<script>
import axios from 'axios';
import { standardFormatTime } from '@/filters/date';
import store from '../../store';
import { getToken } from '@/utils/auth';
import exportImg from '@/assets/export.png';
import { aesEncode } from '@/utils/string';
import { SECRET_KEY } from '@/utils/const';

const {
  BASE_API, AES_OPEN, EXCLUDE_SECRET_URL = []
} = process.env;
export default {
  name: 'ExportButton',
  props: {
    isDiy: {
      type: Boolean,
      default: false
    },
    isBeforeExport: {
      type: Boolean,
      default: false
    },
    httpMethod: {
      type: String,
      default: 'get'
    },
    queryData: { // 导出传入的参数
      type: Object,
      default: () => {
        return {};
      }
    },
    exportApi: { // 导出的api
      type: String,
      default: () => {
        return '';
      }
    },
    exportNameLast: { // 导出文件的名字
      type: String,
      default: () => {
        return '';
      }
    },
    exportName: { // 导出文件的名字
      type: String,
      default: () => {
        return '';
      }
    },
    templateImg: { // 导出模板的img
      type: String,
      default: ''
    },
    width: {
      type: Number,
      default: 16
    },
    height: {
      type: Number,
      default: 16
    },
    tooltipContent: {
      type: String,
      default: '导出'
    },
    defaultLoading: {
      type: Boolean,
      default: true
    },
    format: {
      type: String,
      default: 'xlsx'
    }
  },
  data() {
    return {
      exportImg,
      loading: false,
      cancelAxios: null
    };
  },
  methods: {
    // 设置token
    serviceToken(service) {
      // request拦截器
      service.interceptors.request.use(
        config => {
          const token = store.getters.token || getToken();
          if (token) {
            config.headers.common['token'] = token;
          }
          return config;
        },
        error => {
          console.log(error);
          Promise.reject(error);
        }
      );
    },
    beforeExport() {
      if (this.isBeforeExport) {
        this.$emit('beforeExport');
      } else {
        this.btnExport();
      }
    },
    btnExport(params = null) {
      this.loading = true;
      var source = axios.CancelToken.source();
      const service = axios.create({
        baseURL: BASE_API, // api 的 base_url
        timeout: 1800000, // 请求超时时间
        headers: {
          'Content-Type': 'application/octet-stream',
          'Content-Disposition': 'attachment;filename=kpi.xlsx'
        },
        transformRequest: [data => { // 参数转换
          return typeof data === 'string' ? data : JSON.stringify(data);
        }]
      });
      // 定义取消函数
      this.serviceToken(service);
      const queryData = params || this.queryData;
      // request拦截器
      service.interceptors.request.use(config => this.interceptors(config));
      if (this.httpMethod === 'post') {
        service.post(this.exportApi, queryData, {
          cancelToken: source.token,
          responseType: 'blob',
          headers: {
            'Content-Type': 'application/json'
          }
        }).then(res => {
          this.responseCallback(res);
        }).catch(e => {
          console.error(e);
          this.loading = false;
          const errMsg = typeof e === 'object' ? e.message : e;
          this.$emit('onErrorExport', errMsg || '请求失败');
        });
      } else {
        service.get(this.exportApi, {
          params: queryData,
          responseType: 'blob',
          cancelToken: source.token
        }).then(res => {
          this.responseCallback(res);
        }).catch(e => {
          console.error(e);
          this.loading = false;
          const errMsg = typeof e === 'object' ? e.message : e;
          this.$emit('onErrorExport', errMsg || '请求失败');
        });
      }

      this.cancelAxios = source;
    },
    jsonParase(data) {
      try {
        return JSON.parse(data);
      } catch (error) {
        return {};
      }
    },
    responseCallback(res) {
      this.$emit('onComplate', res);
      this.loading = false;
      const headers = res.headers;
      if (headers && headers['content-type'].indexOf('json') !== -1) {
        const a = new Blob([res.data]);
        const reader = new FileReader();
        reader.onload = e => {
          const result = this.jsonParase(e.target.result);
          if (result.code === 401) { // 用户过期的情况
            this.loading = false;
            this.$confirm(
              '当前登录已过期，请重新登录',
              '',
              {
                confirmButtonText: '重新登录',
                type: 'warning',
                customClass: 'del-message',
                iconClass: 'del-icon',
                showCancelButton: false,
                center: true
              }
            ).then(() => {
              this.loading = false;
              store.dispatch('FedLogOut').then(() => {
                location.reload(); // 为了重新实例化vue-router对象 避免bug
              });
            }).catch(() => {
              this.loading = false;
              return;
            });
          } else if (result.message) {
            this.$emit('onErrorExport', result.message);
            this.$message.error(result.message);
          }
        };
        reader.readAsText(a);
      } else {
        this.loading = false;
        const url = window.URL.createObjectURL(new Blob([res.data]));
        const a = document.createElement('a');
        const time = new Date().getTime();
        a.style.display = 'none';
        a.setAttribute('download', `${this.exportName}${standardFormatTime(time)}${this.exportNameLast}.${this.format}`);
        a.setAttribute('href', url);
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
        this.$emit('onSuccessExport', '导出成功');
      }
    },
    interceptors(config) {
      if (!navigator.onLine) {
        this.$message({
          type: 'warning',
          message: '网络错误！请检查网络状态...'
        });
      }
      if (AES_OPEN && config.data && !EXCLUDE_SECRET_URL.includes(config.url)) {
        const isStr = typeof config.data === 'string' || typeof config.data === 'number';
        config.data = aesEncode(isStr ? config.data : JSON.stringify(config.data), SECRET_KEY);
      }
      return config;
    },
    cancelHttp(msg = '请求已取消') {
      if (this.cancelAxios) {
        this.cancelAxios.cancel(msg);
      }
    }
  }
};
</script>
<style rel="stylesheet/scss" lang="scss">
.meidum-export-btn {
  padding: 0 18px;
  color: #333;
  font-size: 12px;
  height: 24px;
  border-radius: 2px;
  display: flex;
  justify-content: center;
  align-items: center;
  margin-right: 10px;
  cursor: pointer;
  background-color: #e9f0f5;
  border: none;
  &:hover {
    color: #4f9ed6;
  }
  &.not-allow {
    cursor: not-allowed;
  }
  &.dropdown-menu {
    background-color: rgba(255, 255, 255, 0.0);
    color: #606266;
    &:hover {
      color: #406EFF;
    }
  }
}
.export-tooltip {
  padding: 5px 10px;
}
</style>
